//
//  QRCodeViewController.swift
//  mySwift
//
//  Created by 高赛 on 21/09/2016.
//  Copyright © 2016 高赛. All rights reserved.
//

import UIKit
import AVFoundation

class QRCodeViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate{

    @IBOutlet weak var closeBtn: UIBarButtonItem!
    
    @IBOutlet weak var customTabBar: UITabBar!
    // 容器视图
    @IBOutlet weak var containerView: UIView!
    // 容器的高度
    @IBOutlet weak var containerHeightCons: NSLayoutConstraint!
    // 冲击波的顶部约束
    @IBOutlet weak var scanImage: UIImageView!
    // 冲击波image
    @IBOutlet weak var scanLineCons: NSLayoutConstraint!
    // 底部按钮
    @IBOutlet weak var bottombtn: UIButton!
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        customTabBar.selectedItem = customTabBar.items?.first
        customTabBar.delegate = self
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        // 开始动画
        startAnimation()
        // 开始扫描
        satrtScan()
        
    }
    
    // 开启扫描
    private func satrtScan(){
        
        // 判断能否将输入设备(摄像头)添加到会话
        if !session.canAddInput(deviceInput) {
            return
        }else {
            // 添加到会话
            session.addInput(deviceInput)
        }
        
        // 判断能否将输出设备添加到会话
        if !session.canAddOutput(deviceOutput) {
            return
        }else {
            // 添加到会话
            session.addOutput(deviceOutput)
            //rectOfInterest  将手机横放,x:0,y:0指的是手机左上角  width,height指的是横向时的宽高
            let x: CGFloat = containerView.frame.origin.y / view.frame.size.height
            let y: CGFloat = containerView.frame.origin.x / view.frame.size.width
            let width: CGFloat = containerView.frame.size.width / view.frame.size.width
            let height: CGFloat = containerView.frame.size.height / view.frame.size.height
            deviceOutput.rectOfInterest = CGRect(x: x, y: y, width: width, height: height)
        }
        
        // 解析(二维码/条形码)
        deviceOutput.metadataObjectTypes = deviceOutput.availableMetadataObjectTypes
        // 设置输出对象的代理,只要解析成功就会通知代理
        deviceOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
        // 添加预览图层
        view.layer.insertSublayer(previewLayer, at: 0)
        // 将边框图层添加到预览图层上
        previewLayer.addSublayer(drawLayer)
        // 告诉session开始扫描
        session.startRunning()
    }
    
    func startAnimation() {
        
        scanLineCons.constant = -containerHeightCons.constant
        self.view.layoutIfNeeded()
        
        UIView.animate(withDuration: 2) {
            // 修改约束
            self.scanLineCons.constant = self.containerHeightCons.constant
            // 循环次数
            UIView.setAnimationRepeatCount(MAXFLOAT)
            // 强制更新
            self.view.layoutIfNeeded()
        }
        
    }
    
    @IBAction func clickCloseBtn(_ sender: UIBarButtonItem) {
        
        dismiss(animated: true, completion: nil)
        
    }
    
    @IBAction func clickBottomBtn(_ sender: AnyObject) {
        
        let vc = QRCodeCardViewController()
        navigationController?.pushViewController(vc, animated: true)
        
    }
    
    // 扫描会话
    private lazy var session :AVCaptureSession = AVCaptureSession()
    // 输入设备
    private lazy var deviceInput : AVCaptureDeviceInput? = {
        // 摄像头
        let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
        do{
            // 创建输入对象
            let input = try AVCaptureDeviceInput(device: device)
            return input
        }catch {
            print(error)
            return nil
        }
    }()
    // 输出设备
    private lazy var deviceOutput : AVCaptureMetadataOutput = AVCaptureMetadataOutput()
    // 设置预览图层
    private lazy var previewLayer: AVCaptureVideoPreviewLayer = {
        let layer = AVCaptureVideoPreviewLayer(session: self.session)
        
        layer?.frame = UIScreen.main.bounds
        // 3.设置填充模式, 否则4s会有问题
        layer?.videoGravity = AVLayerVideoGravityResizeAspectFill
        return layer!
    }()
    // 设置边框图层
    private lazy var drawLayer: CALayer = {
       let layer = CALayer()
        layer.frame = self.view.frame
        return layer
    }()
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    // 只要解析到数据就会到这里
    public func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
        
        // 获取扫描到的二维码的位置
        // 转换坐标    conners包含4个顶点的坐标
        for object in metadataObjects {
            // 判断当前获取到的数据,是否是机器可识别的类型
            if object is AVMetadataMachineReadableCodeObject {
                let codeObject = previewLayer.transformedMetadataObject(for: object as! AVMetadataObject) as! AVMetadataMachineReadableCodeObject
                drawCorners(codeObject: codeObject)
            }
        }
    }
    
    private func drawCorners(codeObject: AVMetadataMachineReadableCodeObject) {
        clearnCorner()
        // 判断codeObject有没有需要描绘的数据
        if codeObject.corners.isEmpty {
            return
        }
        // 创建一个图层
        let layer = CAShapeLayer()
        layer.lineWidth = 4
        layer.strokeColor = UIColor.red.cgColor
        layer.fillColor = UIColor.clear.cgColor
        // 创建并描绘
        layer.path = cornersPath(corners: codeObject.corners as NSArray!)
        // 将绘制好的图层添加到drawLayer上
        drawLayer.addSublayer(layer)
    }
    
    private func cornersPath(corners: NSArray!) -> CGPath{
        
        // 创建路径 codeObject.corners中包含4个点,遍历四个点描绘路径
        let path = UIBezierPath()
        var index: Int = 0
        var point = CGPoint.zero
        // 取出第一个点,并移动到该点上
        var dict = corners[0]
        point = CGPoint(dictionaryRepresentation: dict as! CFDictionary)!
        path.move(to: point)
        // 将剩下的点添加到路径上
        index += 1
        while index < corners.count{
            dict = corners[index]
            point = CGPoint(dictionaryRepresentation: dict as! CFDictionary)!
            path.addLine(to: point)
            index += 1
        }
        // 关闭路径
        path.close()
        
        return path.cgPath
    }
    
    // 清空矩形
    private func clearnCorner() {
        
        if drawLayer.sublayers == nil || drawLayer.sublayers?.count == 0 {
            return
        }
        for subLayer in drawLayer.sublayers! {
            subLayer.removeFromSuperlayer()
        }
    }
}

extension QRCodeViewController: UITabBarDelegate {
    
    func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
        
        if item.title == "二维码" {
            containerHeightCons.constant = 300
        }else {
            containerHeightCons.constant = 150
        }
        
        self.scanImage.layer.removeAllAnimations()
        
        startAnimation()
    }
    
}
